﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using DeepTime.DL;
using DeepTime.DataSources.DL;
using DeepTime.DL.DataSources;

namespace DeepTime.DeepZoomGenerator
{
    public class WorkerRole : RoleEntryPoint
    {
        #region Methods

        public override void Run()
        {
            while (true)
            {
                //
                // Wait before processing next iteration
                //
                Thread.Sleep(10000);

                //
                // Get next message from the queue
                //
                ImageProcessorQueueDataSource imageProcessorQueueDataSource = new ImageProcessorQueueDataSource();
                CloudQueueMessage message = imageProcessorQueueDataSource.SelectFirst();

                //
                // Check for no message
                //
                if (message != null)
                {
                    //
                    // Seperate partition and row key
                    //
                    string[] data = message.AsString.Split('|');

                    if (data.Length != 2)
                    {
                        imageProcessorQueueDataSource.Delete(message);
                        continue;
                    }

                    string PartitionKey = data[0];
                    string RowKey = data[1];

                    DeepZoomGenerator.CreateImageDeepZoom(PartitionKey, RowKey);
                }

                //
                // Get next message from the queue
                //
                CollageImageProcessorQueueDataSource collageImageProcessorQueueDataSource = new CollageImageProcessorQueueDataSource();
                CloudQueueMessage collageMessage = collageImageProcessorQueueDataSource.SelectFirst();

                //
                // Check for no message
                //
                if (collageMessage != null)
                {
                    //
                    // Seperate partition and row key
                    //
                    string data = collageMessage.AsString;

                    collageImageProcessorQueueDataSource.Delete(collageMessage);

                    DeepZoomGenerator.CreateSparseImageDeepZoom(data);
                }
            }
        }

        public override bool OnStart()
        {
            #region Setup CloudStorageAccount Configuration Setting Publisher

            // This code sets up a handler to update CloudStorageAccount instances when their corresponding
            // configuration settings change in the service configuration file.
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                // Provide the configSetter with the initial value
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (sndr, arg) =>
                {
                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                        .Any((change) => (change.ConfigurationSettingName == configName)))
                    {
                        // The corresponding configuration setting has changed, propagate the value
                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                        {
                            // In this case, the change to the storage account credentials in the
                            // service configuration is significant enough that the role needs to be
                            // recycled in order to use the latest settings. (for example, the 
                            // endpoint has changed)
                            RoleEnvironment.RequestRecycle();
                        }
                    }
                };
            });

            #endregion


            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 48;

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            RoleEnvironment.Changing += RoleEnvironmentChanging;

            return base.OnStart();
        }

        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
        {
            // If a configuration setting is changing
            if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                e.Cancel = true;
            }
        }

        #endregion Methods
    }
}
